#-*-coding:utf-8-*-
import os  
import csv
import numpy as np
import argparse
import chainer
from chainer import Chain,report
from chainer import Parameter,Variable,serializers,optimizers,training
from chainer import links as L
from chainer import functions as F
from chainer.training import extensions
from chainer.datasets import TupleDataset 
from sklearn.model_selection import train_test_split

from model import *

base_path = './data'
BATCH_SIZE = 16
parser = argparse.ArgumentParser(description='intel：game train')
parser.add_argument('--gpu', '-g', type=int, default=-1,
                        help='GPU ID (negative value indicates CPU)')
args = parser.parse_args()
def get_file_path_list(base_path):
    file_list=[]
    for (root,dirs,files) in os.walk(base_path):
        for filename in files:
            if filename.find('arr.txt')!=-1:
                file_list.append(filename)
    file_list.sort()
    return file_list

def get_date(filename): 
    date_list = []
    with open(filename) as f:
        for line in  f.readlines():
            date = line.split("::",1)
            date_list.append(date[0])
    return date_list

def get_one_train_data(file_path):
    file_path = base_path +'/' + file_path
    data = np.genfromtxt(file_path,delimiter='::')
    input_size = data.shape[1]-1
    y_data = data[:,-1].astype('float32')
    date_data = get_date(file_path)
    x_data = np.delete(data,-1,axis=1)
    x_data = np.delete(x_data,0,axis=1)
    return date_data,x_data,y_data



def train_oneday(filename,date_data,x_data,y_data):
    x_data_train = x_data[0:-7]
    y_data_train = y_data[0:-7]
    x_data_predict = x_data[-7:]
    y_data_predict = y_data[-7:]
    date_data_predict = date_data[-7:]
    # Train test split 准备训练数据和测试数据
    tloc, vloc, ty,vy = train_test_split(x_data_train, y_data_train, test_size=0.2,random_state=42)
    train_data = TupleDataset(tloc,ty)
    test_data = TupleDataset(vloc,vy)
    input_size = x_data.shape[1]
    #network and modle 
    model = MyNetwork(input_size)
    #enable gpu
    if args.gpu >= 0:
        # Make a specified GPU current
        chainer.cuda.get_device_from_id(args.gpu).use()
        model.to_gpu()  # Copy the model to the GPU

    # Choose an optimizer algorithm
    optimizer = chainer.optimizers.Adam(alpha=0.0002)
    optimizer.setup(model)

    # train iterators 
    train_iter = chainer.iterators.SerialIterator(train_data, BATCH_SIZE)
    test_iter = chainer.iterators.SerialIterator(test_data, BATCH_SIZE,
                                                repeat=False, shuffle=False)

    # train object 
    updater = training.StandardUpdater(train_iter,optimizer, device=args.gpu)
    trainer = training.Trainer(updater,(500,'epoch'),out='result')
    # train extend
    trainer.extend(extensions.Evaluator(test_iter,model, device=args.gpu))
    trainer.extend(extensions.LogReport())
    trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'validation/main/loss']))
    trainer.extend(extensions.ProgressBar())
    
    trainer.run()
    y_data_predict_train = model.predict(x_data_predict)
    save_one_train(date_data_predict,y_data_predict,y_data_predict_train.data)
    serializers.save_npz('./model/'+filename.rstrip('.txt')+".model",model)
    
def save_one_train(dates,y_true,y_pres):
    with open("result.csv",'a') as f:
        for x in range(len(dates)):
            f.write(dates[x]+"::"+str(("%.6f" % y_true[x]))+"::"+str( y_pres[x][0])+"\n")

    

def train():
    #save_one_train(['date_time'],['y_true'],['y_predict'])
    file_list = get_file_path_list(base_path)
    for filename in file_list:
        print "-----now is training the data is "+filename
        date_data,x_data,y_data = get_one_train_data(filename)
        train_oneday(filename,date_data,x_data,y_data)


def main():
    print args.gpu
    #train()
    '''
    file_list = get_file_path_list(base_path)
    for filename in file_list:
        print filename
    '''
if __name__ == '__main__':
    main()